home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d17
/
flowcntl.arc
/
FLOWCNTL.ASM
next >
Wrap
Assembly Source File
|
1984-12-18
|
4KB
|
165 lines
page 60,132
title flowcntl - alter serial port com1 to use ^S/^Q handshaking
; By: Bruce Walker
; Date: Oct 23, 1984
; Mod: Oct 25, 1984
;
; I hereby give permission to do any damn thing you want with this program
; provided you don't try to blame me for anything naughty it might do.
; It would be nice if you left this title comment block intact if you
; modify it, but feel free to add your own name to the blameless list.
; If you manage to remove any restrictions or otherwise improve it, please
; repost the result.
;
; How to Use (and What it Does):
;
; Set up a batch file (or edit AUTOEXEC.BAT) with a line to set the mode
; of COM1: to the required baud rate, and follow it with a line to invoke
; this program. eg:
;
; mode com1:9600,N,8,1
; flowcntl
;
; which will drive a 9600 baud, no parity, eight data-bit and one stop
; bit serial printer.
;
; The program then loads itself into memory (where it remains until you
; reboot) and intercepts any conversations with COM1 and controls the
; output flow according to the time-honoured ^S/^Q (DC3/DC1 or XON/XOFF)
; protocol.
;
; To control a serial printer, add a line to redirect the LPT1: device
; to the COM1: device. eg:
;
; mode LPT1:=COM1:
;
; Now, if you invoke the PRINT command, and hit return when it asks you
; what device to use for output, your serial printer will buzz away
; happily to itself, while DOS thinks it's talking to a parallel Epson.
;
;
; How To Make:
;
; Do something like the following:
;
; masm flowcntl,,,nul;
; link flowcntl,,nul;
; exe2bin flowcntl flowcntl.com
; del flowcntl.exe
; del flowcntl.obj
;
; It has been tested with PC-DOS 2.1 and with printers up to 9600 baud.
; Because it operates at the BIOS level, it should also work with early
; DOS's like DOS 1.1 .
;
; Limitations:
;
; - this is an unabashed hack (it is NOT a "device driver", it should be).
; - uses ("user-definable") interrupt 60H; this may conflict with
; someone, somewhere.
; - only uses com1:.
; - does not work with BIOS-internal routines such as "PRINT_SCREEN" (I
; am not sure why) therefore the "<SHIFT> PrtSc" button should not be
; pressed.
; - as a consequence of the above, Wordstar (for example) does not work
; with this code so don't invoke it when using Wordstar, just use WS's
; WINSTALL program to set up their internal serial printer drivers.
abs0 segment at 0 ; this is where the interrupt vectors live
org 50h ; int 14h - rs232 io handler vector
com_off dw ?
com_seg dw ?
org 180h ; int 60h - user-definable (so I used it!)
int60_o dw ?
int60_s dw ?
abs0 ends
code segment
assume cs:code, ds:abs0
org 100h
main proc far ; set up pointers to intercept calls to rs232 handler
; and arrange for this piece of code to remain in memory
; forever after.
xor ax,ax ; ds := absolute 0 segment
mov ds,ax
mov ax,com_off ; copy rs232 vectors to int 60h
mov int60_o,ax
mov ax,com_seg
mov int60_s,ax
cli ; copy pointer to new handler to int 14h
mov com_off,offset intercept
mov ax,cs
mov com_seg,ax
sti
mov dx,offset next_byte ; point to end of program
int 27h ; terminate but stay resident
id_code db "FLOWCNTL V1.0 Bruce Walker 1984"
flag db 'Q'-40h ; ^S means stop - ^Q means go again
; Whenever someone calls the rs232 (int 14h) handler now, we intercept and
; if the call was a "test serial line status"-type (command code 3 in AH),
; check for control-S / control-Q handshaking from the serial device. We
; translate the serial handshake into a "fake" CTS bit in the status register
; by setting or resetting the CTS status bit in AH as appropriate, and passing
; it back to the calling program.
intercept:
sti
push ds
push cs ; set data seg to current code segment
pop ds
assume ds:code
or dx,dx ; we only twiddle com1
jz com1
let_em_go:
int 60h ; let call thru unaltered
beat_it:
pop ds
iret
com1:
cmp ah,3 ; status call?
jne let_em_go
int 60h ; get status bytes into ax
push ax
and ah,01h ; any rx'ed chars?
jz c3
mov ah,2 ; rx
int 60h
cmp al,'S'-40h
je c2
cmp al,'Q'-40h
jne c3
c2:
mov byte ptr flag,al
c3:
cmp flag,'S'-40h
pop ax
jne c4
and al,10h ; CTS low
jmp beat_it
c4:
or al,10h ; CTS high
jmp beat_it
next_byte:
main endp
code ends
end main